/*
 * Copyright 2011-2012 Redia A/S
 * 
 * This file is part of Redias Library App for Android.
 *
 *  Redia Library App for Android is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Redia Library App for Android is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with Redia Library App for Android.  If not, see <http://www.gnu.org/licenses/>.
 */
package dk.redia.libraryapp.net;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import dk.redia.lib.log.Log;
import android.widget.Toast;
import dk.redia.lib.utils.AppApplication;
import dk.redia.lib.utils.AppConfiguration;
import dk.redia.lib.xmlrpc.XmlRpcClientResultListener;
import dk.redia.lib.xmlrpc.XmlRpcResultDumper;
import dk.redia.lib.xmlrpc.XmlRpcResultUtils;
import dk.redia.libraryapp.R;
import dk.redia.libraryapp.xmlrpc.library.XmlRpcClient;

public class CoverUrlCache {
	
	protected static final String logTag = "CoverUrlCache";

	private Map<String, String> coverUrls;
	
	private static CoverUrlCache instance;
	
	public static final CoverUrlCache getInstance() {
		if (instance==null) {
			instance = new CoverUrlCache();
		}
		return instance;
	}
	
	private CoverUrlCache() {
		coverUrls = new HashMap<String, String>();
	}
	
	public boolean hasCache(String identifier) {
		return coverUrls.containsKey(identifier);
	}
	
	public String getCoverUrlSync(String coverId) {
		if (hasCache(coverId)) {
			return coverUrls.get(coverId);
		} else {
			return null;
		}
	}
	
	public void getCoverUrl(Set<String> coverIds, final CoverUrlCacheListener l) {
		
		final List<String> missingCoverIds = new ArrayList<String>();
		Map<String, String> localResult = new HashMap<String, String>();
		for (String coverId : coverIds) {
			if (!coverUrls.containsKey(coverId)) {
				missingCoverIds.add(coverId);
			} else {
				localResult.put(coverId, coverUrls.get(coverId));
			}
		}

		if (localResult.size()>0) {
			l.gotCoverUrls(localResult);
		}

		String[] missingCoverIdsArr = new String[missingCoverIds.size()];
		missingCoverIds.toArray(missingCoverIdsArr);
		
		if (missingCoverIds.size()>0) {
			XmlRpcClient.getInstance().getCoverUrl(AppConfiguration.getInstance().getCustomerId(), AppConfiguration.getInstance().getApiKey(), missingCoverIdsArr, new XmlRpcClientResultListener() {
				
				public void callFailed(String message) {
					Log.w(CoverUrlCache.logTag, "Failed to retrieve cover URL from web service: " + message);
					AppApplication.toast(R.string.failedToRetrieveCoverUrlsText, Toast.LENGTH_LONG);
				}
				
				public void callCompleted(Object resultObj) {
					XmlRpcResultDumper.dump(resultObj);
					Map<String, Object> result = XmlRpcResultUtils.unpackStandardResult(resultObj);
					Boolean resultResult = (Boolean)result.get("result");
					if (resultResult) {
						Map<String, Object> resultData = XmlRpcResultUtils.unpackStruct(result.get("data"));
						if (resultData!=null) {
							Map<String, String> newIdentifiersToUrls = new HashMap<String, String>();
							for (String identifier : resultData.keySet()) {
								String url = (String)resultData.get(identifier);
								if (url!=null) {
									if (!url.equals("")) {
										newIdentifiersToUrls.put(identifier, url);
//										l.gotCoverUrl(id,  url);
										Log.d(CoverUrlCache.logTag, "Caching cover URL " + url + " for identifier " + identifier);
										coverUrls.put(identifier, url);
									} else {
										Log.w(CoverUrlCache.logTag, "Empty Cover URL received");
									}
								} else {
									Log.w(CoverUrlCache.logTag, "No entry for identifier " + identifier);
								}	
							}
							if (newIdentifiersToUrls.size()>0) {
								l.gotCoverUrls(newIdentifiersToUrls);
							} else {
								Log.w(logTag, "No URLs in response to getCoverUrl");
							}
						} else {
							Log.w(CoverUrlCache.logTag, "Unable to parse data as struct");
						}
					} else {
						Log.e(CoverUrlCache.logTag, "Failed to retrieve cover URL: " + result.get("message"));
					}
				}
			});
		}
	}
}
